package project.platform;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Vector;

import org.kxml.Xml;
import org.kxml.io.XmlWriter;
import org.kxml.kdom.Document;
import org.kxml.kdom.Element;
import org.kxml.parser.XmlParser;

import project.Animal;

/**
 *  Handles encoding and decoding Animal objects to and from XML.
 *  Depends on the kxml framework.
 *  
 *  @author Paul Magrath - 05379725
 *
 */
public class XML {
	
	/** Encode Animal to XML using the kxml framework. 
	 * @param a Animal to encode
	 * @return XML in a String
	 */
    public static String encodeToXML(final Animal a){
    	final ByteArrayOutputStream out = new ByteArrayOutputStream();
    	final XmlWriter writer = new XmlWriter(new OutputStreamWriter( out ) );
    	try {
			writer.startTag("animal");
				writer.startTag("name");
					writer.write(a.name);
		        writer.endTag();
				writer.startTag("owner");
					writer.write(a.owner);
				writer.endTag();
				writer.startTag("class");
					writer.write(a.classID);
		        writer.endTag();
				writer.startTag("size");
					writer.write(new String(""+a.size));
				writer.endTag();
				writer.startTag("speed");
					writer.write(new String(""+a.speed));
				writer.endTag();
				writer.startTag("strength");
					writer.write(new String(""+a.str));
		        writer.endTag();
				writer.startTag("dexterity");
					writer.write(new String(""+a.dex));
		        writer.endTag();
				writer.startTag("intelligence");
					writer.write(new String(""+a.intel));
				writer.endTag();
				writer.startTag("humour");
					writer.write(new String(""+a.humour));
		        writer.endTag();
				writer.startTag("xPosition");
					writer.write(new String(""+a.xpos));
				writer.endTag();
				writer.startTag("yPosition");
					writer.write(new String(""+a.ypos));
				writer.endTag();
				writer.startTag("wins");
					writer.write(new String(""+a.wins));
				writer.endTag();
				writer.startTag("losses");
					writer.write(new String(""+a.losses));
				writer.endTag();
		     writer.endTag();
		} catch (final IOException e) {
			e.printStackTrace();
		}
    	
    	return out.toString();
    }
    
    /** Decode Animal(s) from XML
     * @param x XML file to decode.
     * @return An array of Animal objects formed from the XML.
     */
    public static Animal[] decodeFromXML(final String x){
		XmlParser parser = null;
		Document doc = new Document();
		final Vector animals = new Vector();

		try {
			// Read in the resource
			final InputStream in = new ByteArrayInputStream(x.getBytes());
			// Turn it into a reader
			final InputStreamReader isr = new InputStreamReader(in);
			// initialize the parser with it.   
			parser = new XmlParser( isr );
			
			// Pass the parser to the document.  At this point the
			// entire resource is parsed and now resides in memory.
			doc.parse( parser );

			parser = null;
		} catch (final IOException ioe) {
			// report error
			System.err.println("XML Parsing Error: " + ioe);
			ioe.printStackTrace();

			parser = null;
			doc = null;
			
			return null;
		} 

		// Now we get the root element which is "xml"
		final Element root = doc.getRootElement();
		// Since the <animal> tags are children of <xml>
		// the we get the children of root and see which one is
		// called <animal>.  We can't just say root.getElement("animal")
		// because it will return an exception if more than one element
		// with that name exists
		final int child_count = root.getChildCount();

		for (int i = 0; i < child_count ; i++ ) {
			if (root.getType(i) != Xml.ELEMENT)
				continue;
						
			Element animalXML = root.getElement(i);
			
			// it's not an animal? continue
			if (!animalXML.getName().equals("animal"))
				continue;

			// it is an animal, so let's print out the contents
			System.err.println("--[ ANIMAL ]--------------------");
			
			final Animal a = new Animal(animalXML.getElement("name").getText(0));
			
			// traverse that portion of the tree looking for contents
			// and printing them out
			final int item_count = animalXML.getChildCount();

			for (int j = 0; j < item_count ; j++) {
				// if it's not an element tag then skip it
				if (animalXML.getType(j) != Xml.ELEMENT)
					continue;
		
				Element item = animalXML.getElement(j);
				
				a.setValue(item.getName(),item.getText(0));
				
				System.err.println( item.getName() + ": " + item.getText(0));
				
				
				item = null;
			}
			
			animals.addElement(a);
			
			System.err.println("---------------------------------\n");
			
			animalXML = null;
		}
		
		final Animal[] animalObjects = new Animal[animals.size()];
		animals.copyInto(animalObjects);
		return animalObjects;
	}
    
    
}
